<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
// import { useUserStore, useStudentStore } from '../../stores'
import { TUser } from '../../Types/user'
import defaultImg from '../../assets/Images/MIUI03.jpg'
import { ElMessage } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import router from '../../router'
import { getUserByUserInfoService, updateUserService } from '../../api/user'
import { Back } from '@element-plus/icons-vue'
import { useRoute } from 'vue-router'
import { standardDateTime } from '../../Tools/Time/date'
import { TClass } from '@/Types/education.d'
import { getClassListByUserIdService } from '../../api/user_classname'
import { getFileSpecificService, uploadFileService } from '../../api/file'
import { useUserStore } from '../../stores'
import { getOperationLogList } from '../../api/operationLog'
import { baseURL } from '@/utils/request'
import { clearPinia } from '@/Tools/function/clearPinia'

// 初始化
const loading = ref(false)
const reviseDialogLoading = ref(false)
const userInfo = ref<TUser>({
	userId: '',
	account: '',
	password: '',
	avatarId: undefined, // number类型或undefined
	avatar: '',
	userTypeId: '',
	typeNumber: '',
	createTime: '',
	updateTime: ''
})
const singleClassInfo = ref<TClass>({
	classId: 0,
	level: '',
	academy: '',
	major: '',
	grade: 0,
	classname: 0,
	createTime: '',
	updateTime: ''
})
const multipleClassInfo = ref<TClass[]>([])
const reviseUserInfo = ref<TUser>({
	userId: 0,
	account: '',
	password: '',
	avatarId: undefined, // number类型或undefined
	avatar: '',
	userTypeId: '',
	createTime: '',
	updateTime: ''
})

/**
 * 弹窗
 */
const reviseFormRef = ref()
const reviseDialog = ref(false)
// 开启弹窗
const reviseBaseInfo = () => {
	reviseDialog.value = true
	reviseUserInfo.value = userInfo.value
}
// 关闭弹窗
const closeReviseDialog = () => {
	reviseFormRef.value.resetFields()
	reviseDialogLoading.value = false
	reviseDialog.value = false
}

/**
 * 修改用户信息
 */
// 上传图片
interface TFile {
	raw: File
}
const imageUrl = ref('')
const avatarChange = (file: TFile) => {
	const fileType = file.raw.type === 'image/jpeg' || file.raw.type === 'image/png'
	const fileSize = file.raw.size / 1024 / 1024 < 3
	if (!fileType || !fileSize) {
		ElMessage.error('上传头像图片只能是 JPG/PNG 格式，且大小不能超过 3MB!')
		return
	}
	// 创建本地预览URL
	imageUrl.value = URL.createObjectURL(file.raw)
	reviseUserInfo.value.avatar = file.raw // 将文件对象存储到avatar字段
	// console.log(form.value)
}
const reviseInfo = async () => {
	reviseDialogLoading.value = true

  try {
    // 密码修改优先执行
    const passwordSuccess = await handlePasswordUpdate();
    if (passwordSuccess) {
      await clearUserInfo();
    }

    // 头像修改
    await handleAvatarUpdate();
  } finally {
    closeReviseDialog();
    reviseDialogLoading.value = false;
  }
};

// 密码修改处理
const handlePasswordUpdate = async () => {
  if (!reviseUserInfo.value.password?.trim()) return false;
  
  try {
    const result = await updateUserService({
      password: reviseUserInfo.value.password,
      userId: reviseUserInfo.value.userId
    });
    
    if (result.data.code === 1) {
      ElMessage.success('密码修改成功');
      return true;
    }
    ElMessage.error('密码修改失败');
  } catch (error) {
    ElMessage.error('密码修改异常');
  }
  return false;
};

// 清除用户信息
const clearUserInfo = async () => {
	clearPinia()

	router.push('/login')
};

// 头像修改处理
const handleAvatarUpdate = async () => {
  const avatar = reviseUserInfo.value.avatar;
  if (!(avatar instanceof File)) return;

  const formData = new FormData();
  formData.append('userId', storeUserId);
  formData.append('file', avatar);
  formData.append('fileType', 'avatar');

  try {
    const result = await uploadFileService(formData);
    result.data.code === 1 
      ? ElMessage.success('头像上传成功') 
      : ElMessage.error('头像上传失败');
  } catch (error) {
    ElMessage.error('头像上传异常');
  }
};

/**
 * 数据处理
 */
const userTypeName = computed(() => {
	const typeMap = {
		1: '学生',
		2: '教师',
		3: '辅导员',
		4: '管理员'
	}
	return typeMap[userInfo.value?.userTypeId as keyof typeof typeMap] || '未知类型'
})

/**
 * 获取数据
 */
// 获取用户信息
const userId = ref(0)
const route = useRoute()
// 从路由参数中获取userId
userId.value = Number(route.params.userId) || 0
const userStore = useUserStore()
const storeUserId = userStore.userInfo.userInfo.userId

const getUserInfo = async () => {
	// console.log('当前用户ID:', userId.value)

	if (!userId.value || isNaN(userId.value)) {
		ElMessage.error('用户ID无效')
		return
	}

	const res = await getUserByUserInfoService({ userId: userId.value })
	if (res.data.code === 1) {
		userInfo.value = res.data.data[0]
		// 获取到用户信息后立即获取头像
		if (userInfo.value.avatarId) {
			await getUserAvatar()
		}
	} else {
		ElMessage.error('获取用户信息失败')
	}
}
// 获取班级信息
const getUserClassInfo = async () => {
	if (!userId.value || isNaN(userId.value)) {
		ElMessage.error('携带的userId无效')
		return
	}

	const res = await getClassListByUserIdService(userId.value)
	if (res.data.code === 1 && res.data.data.length === 1) {
		singleClassInfo.value = res.data.data[0]
	} else if (res.data.code === 1 && res.data.data.length > 1) {
		multipleClassInfo.value = res.data.data
	} else {
		ElMessage.error('获取班级信息失败')
	}
	// console.log(res.data.data)
}
// 查看班级信息
const handleLookClassInfo = (row: TClass) => {
	// console.log(row)
	router.push(`/classScoreInfo/${row.classId}`)
}
// 获取头像
const getUserAvatar = async () => {
	if (!userInfo.value.avatarId) return

	loading.value = true
	try {
		const res = await getFileSpecificService({ id: userInfo.value.avatarId, fileType: 'avatar' })
		if (res.data.code === 1 && res.data.data) {
			// 处理数据
			const url = baseURL + '/public/uploads/' + res.data.data[0].fileName
			// console.log(url);
			userInfo.value.avatar = url
		}
	} catch (error) {
		// console.error('获取头像出错:', error)
	} finally {
		loading.value = false
	}
}

// 返回上一个页面
const goBack = () => {
	router.go(-1)
}

// 操作日志相关
interface OperationLog {
	id: number
	userId: number
	method: string
	url: string
	params: string
	ip: string
	address: string
	timeCost: number
	createTime: string
}

const operationLogs = ref<OperationLog[]>([])
const logsTimeRange = ref('all')
const currentPage = ref(1)
const pageSize = ref(10)
const totalLogs = ref(0)
const logsLoading = ref(false)

// 获取操作日志
const getOperationLogs = async () => {
	if (!userId.value || isNaN(userId.value)) {
		return
	}

	logsLoading.value = true
	try {
		const res = await getOperationLogList(userId.value)
		if (res.data.code === 1) {
			// console.log(res.data.data)
			operationLogs.value = res.data.data.slice(0, 5)
			totalLogs.value = res.data.data.length
		} else {
			ElMessage.error('获取操作日志失败')
		}
	} catch (error) {
		console.error('获取操作日志出错:', error)
		ElMessage.error('获取操作日志出错')
	} finally {
		logsLoading.value = false
	}
}

// 分页处理函数
const handleSizeChange = (newSize: number) => {
	pageSize.value = newSize
}

const handleCurrentChange = (newPage: number) => {
	currentPage.value = newPage
}

// 处理时间范围变化
const handleLogTimeChange = (value: string) => {
	// 前端筛选时间范围
	if (value === 'week') {
		const oneWeekAgo = new Date()
		oneWeekAgo.setDate(oneWeekAgo.getDate() - 7)

		// 再次获取所有日志，然后前端过滤
		getOperationLogList(userId.value).then((res) => {
			if (res.data.code === 1) {
				const filteredLogs = res.data.data.filter((log: OperationLog) => {
					const logDate = new Date(log.createTime)
					return logDate >= oneWeekAgo
				})
				operationLogs.value = filteredLogs
				totalLogs.value = filteredLogs.length
			}
		})
	} else if (value === 'month') {
		const oneMonthAgo = new Date()
		oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1)

		// 再次获取所有日志，然后前端过滤
		getOperationLogList(userId.value).then((res) => {
			if (res.data.code === 1) {
				const filteredLogs = res.data.data.filter((log: OperationLog) => {
					const logDate = new Date(log.createTime)
					return logDate >= oneMonthAgo
				})
				operationLogs.value = filteredLogs
				totalLogs.value = filteredLogs.length
			}
		})
	} else {
		// 默认获取全部
		getOperationLogs()
	}
}

// 根据操作类型获取不同的图标类型
const getLogTypeByOperation = (method: string) => {
	if (method === 'POST') return 'success'
	if (method === 'PUT') return 'warning'
	if (method === 'DELETE') return 'danger'
	if (method === 'GET') return 'info'

	return 'info' // 默认返回info类型
}

// 根据操作类型获取不同的颜色
const getLogColorByOperation = (method: string) => {
	if (method === 'POST') return '#67C23A' // 绿色
	if (method === 'PUT') return '#E6A23C' // 黄色
	if (method === 'DELETE') return '#F56C6C' // 红色
	if (method === 'GET') return '#409EFF' // 蓝色

	return '#909399' // 默认返回灰色
}

// 获取操作描述
const getOperationDescription = (log: OperationLog) => {
	// 根据URL和方法生成描述
	const urlParts = log.url.split('/')
	const lastPart = urlParts[urlParts.length - 1]

	let description = ''
	let paramsObj = {}

	// 尝试解析params
	try {
		if (log.params && (log.params.startsWith('[') || log.params.startsWith('{'))) {
			paramsObj = JSON.parse(log.params)
			// 如果是数组，取第一个元素
			if (Array.isArray(paramsObj) && paramsObj.length > 0) {
				paramsObj = paramsObj[0]
			}
		}
	} catch (e) {
		console.error('解析参数失败:', e)
	}

	// 根据URL和method以及params生成描述
	if (lastPart === 'users' || lastPart === 'user') {
		if (log.method === 'POST') {
			description = '添加个人信息'
		} else if (log.method === 'PUT') {
			// 检查是否包含特定字段来提供更精确的描述
			if (paramsObj && typeof paramsObj === 'object') {
				if ('password' in paramsObj) {
					description = '修改个人密码'
				} else if ('avatar' in paramsObj || 'avatarId' in paramsObj) {
					description = '更新个人头像'
				} else {
					description = '修改个人信息'
				}
			} else {
				description = '修改个人信息'
			}
		} else if (log.method === 'DELETE') {
			description = '删除个人信息'
		}
	} else if (lastPart === 'login') {
		description = '用户登录'
	} else if (lastPart === 'logout') {
		description = '用户登出'
	} else if (lastPart === 'scores' || lastPart === 'score') {
		if (log.method === 'POST') {
			description = '添加成绩信息'
		} else if (log.method === 'PUT') {
			description = '修改成绩信息'
		} else if (log.method === 'DELETE') {
			description = '删除成绩信息'
		} else if (log.method === 'GET') {
			description = '查询成绩信息'
		}
	} else if (lastPart === 'classes' || lastPart === 'class') {
		if (log.method === 'POST') {
			description = '添加班级信息'
		} else if (log.method === 'PUT') {
			description = '修改班级信息'
		} else if (log.method === 'DELETE') {
			description = '删除班级信息'
		} else if (log.method === 'GET') {
			description = '查询班级信息'
		}
	} else {
		// 默认描述
		switch (log.method) {
			case 'POST':
				description = `添加${lastPart}信息`
				break
			case 'PUT':
				description = `修改${lastPart}信息`
				break
			case 'DELETE':
				description = `删除${lastPart}信息`
				break
			case 'GET':
				description = `查询${lastPart}信息`
				break
			default:
				description = `${log.method}操作`
		}
	}

	return description
}

// 获取请求参数的格式化展示
const getFormattedParams = (paramsStr: string) => {
	try {
		// 检查是否是字符串形式的数组或对象
		if (paramsStr.startsWith('[') || paramsStr.startsWith('{')) {
			const params = JSON.parse(paramsStr)
			return JSON.stringify(params, null, 2)
		}
		return paramsStr
	} catch (e) {
		return paramsStr
	}
}

onMounted(() => {
	getUserInfo()
	getUserClassInfo()
	getOperationLogs()
})
</script>

<template>
	<div class="header" v-if="userId != storeUserId">
		<el-button @click="goBack">
			<el-icon><Back /></el-icon>
		</el-button>
	</div>
	<div class="userInfo" v-loading="loading">
		<!-- 头像等区域 -->
		<div class="avatar_area">
			<el-avatar :size="100" :src="userInfo.avatar ? userInfo.avatar : defaultImg"></el-avatar>
			<div class="right_body">
				<div class="name">{{ userInfo.uname }}</div>
			</div>
			<!-- <el-button @click="onQuit" type="primary">退出</el-button> -->
		</div>

		<!-- 分割线 -->
		<el-divider></el-divider>

		<!-- 使用标签页组织内容 -->
		<el-tabs type="card" class="user-tabs">
			<!-- 基本信息标签页 -->
			<el-tab-pane label="基本信息">
				<el-card class="basic-info-card">
					<template #header>
						<div class="card-header">
							<span>基本信息</span>
							<el-button @click="reviseBaseInfo" type="primary" v-if="userId === storeUserId"
								>修改</el-button
							>
						</div>
					</template>

					<div class="info-grid">
						<div class="info-item">
							<span class="info-label">用户ID：</span>
							<span class="info-value">{{ userInfo.userId }}</span>
						</div>
						<div class="info-item">
							<span class="info-label">用户类型：</span>
							<span class="info-value">{{ userTypeName }}</span>
						</div>
						<div class="info-item">
							<span class="info-label">账号：</span>
							<span class="info-value">{{ userInfo.account }}</span>
						</div>
						<div class="info-item" v-if="userInfo.userTypeId === 1">
							<span class="info-label">学号：</span>
							<span class="info-value">{{ userInfo.typeNumber }}</span>
						</div>
						<div class="info-item">
							<span class="info-label">密码：</span>
							<span class="info-value">******</span>
						</div>
						<div class="info-item">
							<span class="info-label">注册时间：</span>
							<span class="info-value">{{
								standardDateTime(userInfo.createTime ? userInfo.createTime : '')
							}}</span>
						</div>
						<div class="info-item">
							<span class="info-label">修改时间：</span>
							<span class="info-value">{{
								standardDateTime(userInfo.updateTime ? userInfo.updateTime : '')
							}}</span>
						</div>
					</div>
				</el-card>

				<!-- 单班级信息 -->
				<el-card class="class-info-card" v-if="userInfo.userTypeId === 1">
					<template #header>
						<div class="card-header">
							<span>班级信息</span>
						</div>
					</template>
					<div class="info-grid">
						<div class="info-item">
							<span class="info-label">学历：</span>
							<span class="info-value">{{
								singleClassInfo.level === 'undergrad' ? '本科' : '专科'
							}}</span>
						</div>
						<div class="info-item">
							<span class="info-label">年级：</span>
							<span class="info-value">{{ singleClassInfo.grade }}</span>
						</div>
						<div class="info-item">
							<span class="info-label">学院：</span>
							<span class="info-value">{{ singleClassInfo.academy }}</span>
						</div>
						<div class="info-item">
							<span class="info-label">班级：</span>
							<span class="info-value">{{ singleClassInfo.classname }}</span>
						</div>
						<div class="info-item">
							<span class="info-label">专业：</span>
							<span class="info-value">{{ singleClassInfo.major }}</span>
						</div>
						<div class="info-item">
							<span class="info-label">创建时间：</span>
							<span class="info-value">{{
								standardDateTime(singleClassInfo.createTime ? singleClassInfo.createTime : '')
							}}</span>
						</div>
						<div class="info-item">
							<span class="info-label">修改时间：</span>
							<span class="info-value">{{
								standardDateTime(singleClassInfo.updateTime ? singleClassInfo.updateTime : '')
							}}</span>
						</div>
					</div>
				</el-card>

				<!-- 多班级信息 -->
				<el-card class="class-list-card" v-if="userInfo.userTypeId !== 1">
					<template #header>
						<div class="card-header">
							<span>管理的班级</span>
						</div>
					</template>
					<el-table :data="multipleClassInfo" stripe style="width: 100%">
						<el-table-column prop="level" label="学历" width="100">
							<template #default="scope">
								{{ scope.row.level === 'undergrad' ? '本科' : '专科' }}
							</template>
						</el-table-column>
						<el-table-column prop="academy" label="学院" width="180" />
						<el-table-column prop="major" label="专业" width="240" />
						<el-table-column prop="grade" label="年级" width="120" />
						<el-table-column prop="classname" label="班级" width="100" />
						<el-table-column label="操作" width="140">
							<template #default="scope">
								<el-button type="primary" size="small" @click="handleLookClassInfo(scope.row)"
									>查看</el-button
								>
							</template>
						</el-table-column>
					</el-table>
				</el-card>
			</el-tab-pane>

			<!-- 操作记录标签页 -->
			<el-tab-pane label="操作记录" v-if="userId === storeUserId">
				<el-card class="operation-log-card">
					<template #header>
						<div class="card-header">
							<span>操作记录</span>
							<div class="header-actions">
								<el-radio-group v-model="logsTimeRange" size="small" @change="handleLogTimeChange">
									<el-radio-button label="all">全部</el-radio-button>
									<el-radio-button label="week">最近一周</el-radio-button>
									<el-radio-button label="month">最近一个月</el-radio-button>
								</el-radio-group>
								<el-button type="primary" size="small" @click="getOperationLogs">刷新</el-button>
							</div>
						</div>
					</template>

					<div v-if="operationLogs.length > 0" class="operation-logs">
						<el-timeline>
							<el-timeline-item
								v-for="(log, index) in operationLogs"
								:key="index"
								:timestamp="standardDateTime(log.createTime)"
								:type="getLogTypeByOperation(log.method)"
								:color="getLogColorByOperation(log.method)"
							>
								<el-card class="log-card">
									<h4>{{ getOperationDescription(log) }}</h4>
									<!-- <p class="log-details">{{ getFormattedParams(log.params) }}</p> -->
									<div class="log-meta">
										<span class="ip-address">IP: {{ log.ip }}</span>
										<span class="address">位置: {{ log.address }}</span>
										<span class="time-cost">耗时: {{ log.timeCost }}ms</span>
									</div>
								</el-card>
							</el-timeline-item>
						</el-timeline>
					</div>
					<el-empty v-else description="暂无操作记录" :image-size="100"></el-empty>

					<div v-if="operationLogs.length > 0" class="pagination-container">
						<el-pagination
							v-model:current-page="currentPage"
							v-model:page-size="pageSize"
							:page-sizes="[10, 20, 50, 100]"
							layout="total, sizes, prev, pager, next, jumper"
							:total="totalLogs"
							@size-change="handleSizeChange"
							@current-change="handleCurrentChange"
						/>
					</div>
				</el-card>
			</el-tab-pane>
		</el-tabs>

		<!-- 修改用户信息弹窗 -->
		<el-dialog
			v-model="reviseDialog"
			:before-close="closeReviseDialog"
			title="修改用户信息"
			center
			width="40%"
			class="reviseUserInfoDialog"
		>
			<el-form
				ref="reviseFormRef"
				:model="reviseUserInfo"
				v-loading="reviseDialogLoading"
				label-width="90px"
				class="dialog-form"
			>
				<div class="form-left">
					<el-form-item prop="userId" label="用户ID：" class="dialog-form-item">{{
						userInfo.userId
					}}</el-form-item>
					<el-form-item prop="userTypeId" label="用户类型：" class="dialog-form-item">{{
						userTypeName
					}}</el-form-item>
					<el-form-item prop="account" label="账号：" class="dialog-form-item">{{
						userInfo.account
					}}</el-form-item>
				</div>
				<div class="form-right">
					<el-form-item prop="password" label="密码：" class="dialog-form-item">
						<el-input v-model="reviseUserInfo.password" type="password" />
					</el-form-item>
					<el-form-item prop="avatarId" label="头像：" class="dialog-form-item">
						<el-upload
							ref="uploadRef"
							class="avatar-uploader"
							:limit="1"
							:accept="['image/jpeg', 'image/png']"
							title="仅支持上传3MB以内的JPG/PNG格式图片"
							:auto-upload="false"
							:show-file-list="false"
							@change="avatarChange"
						>
							<img v-if="imageUrl" :src="imageUrl" class="avatar" />
							<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
						</el-upload>
					</el-form-item>
				</div>
			</el-form>
			<template #footer>
				<span class="dialog-footer">
					<el-button @click="closeReviseDialog">取消</el-button>
					<el-button type="primary" @click="reviseInfo">确定</el-button>
				</span>
			</template>
		</el-dialog>
	</div>
</template>

<style lang="scss" scoped>
.header {
	padding-bottom: 10px;
	border-bottom: 1px solid var(--el-border-color);
}

.userInfo {
	display: flex;
	flex-direction: column;
	margin-top: 10px;

	.avatar_area {
		box-sizing: border-box;
		padding: 10px;
		display: flex;
		align-items: center;

		.el-avatar {
			margin-right: 20px;
		}

		.right_body {
			display: flex;
			flex-wrap: wrap;
			align-content: center;

			.name {
				font-size: 25px;
				font-weight: 500;
			}

			.content {
				font-size: small;
				color: var(--el-text-color-secondary);
			}
		}
	}

	.user-tabs {
		margin-top: 20px;

		// 卡片样式
		.basic-info-card,
		.class-info-card,
		.class-list-card,
		.operation-log-card {
			margin-bottom: 20px;
			border-radius: 8px;
			box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);

			.card-header {
				display: flex;
				justify-content: space-between;
				align-items: center;

				.header-actions {
					display: flex;
					gap: 10px;
				}
			}
		}

		// 信息网格布局
		.info-grid {
			display: grid;
			grid-template-columns: repeat(2, 1fr);
			gap: 16px;

			@media (max-width: 768px) {
				grid-template-columns: 1fr;
			}

			.info-item {
				display: flex;
				align-items: baseline;

				.info-label {
					min-width: 100px;
					color: var(--el-text-color-secondary);
					font-weight: 500;
				}

				.info-value {
					flex: 1;
					word-break: break-word;
				}
			}
		}

		// 操作日志样式
		.operation-logs {
			padding: 10px 0;

			.log-card {
				margin-bottom: 10px;

				h4 {
					margin: 0 0 8px;
					font-size: 16px;
					font-weight: 500;
				}

				.log-details {
					color: var(--el-text-color-regular);
					margin-bottom: 8px;
				}

				.log-params {
					margin: 8px 0;

					pre {
						background-color: #f8f8f8;
						padding: 8px;
						border-radius: 4px;
						font-family: monospace;
						font-size: 12px;
						white-space: pre-wrap;
						word-break: break-all;
					}
				}

				.log-meta {
					display: flex;
					justify-content: space-between;
					align-items: center;
					font-size: 12px;
					color: var(--el-text-color-secondary);

					.ip-address,
					.address,
					.time-cost {
						font-family: monospace;
						margin-right: 10px;
					}
				}
			}
		}

		.pagination-container {
			margin-top: 20px;
			display: flex;
			justify-content: center;
		}
	}

	.reviseUserInfoDialog {
		.dialog-form {
			display: flex;
			width: 100%;

			.form-left {
				flex: 3;
			}

			.form-right {
				flex: 4;
			}

			.dialog-form-item {
				margin-bottom: 10px;
			}

			.avatar-uploader {
				border: 1px dashed var(--el-border-color);
				border-radius: 6px;
				cursor: pointer;
				position: relative;
				overflow: hidden;
				transition: var(--el-transition-duration-fast);

				&:hover {
					border-color: var(--el-color-primary);
				}
			}

			.avatar-uploader-icon {
				font-size: 28px;
				color: #8c939d;
				width: 120px;
				height: 120px;
				text-align: center;
				line-height: 120px;
			}

			.avatar {
				width: 120px;
				height: 120px;
				display: block;
				object-fit: cover;
			}
		}
	}
}
</style>
